home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / pc / DirectX SDK / DXSDK / samples / Multimedia / Common / src / d3dfile.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-31  |  23.6 KB  |  809 lines

  1. //-----------------------------------------------------------------------------
  2. // File: D3DFile.cpp
  3. //
  4. // Desc: Support code for loading DirectX .X files.
  5. //
  6. // Copyright (c) 1997-2001 Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #define STRICT
  9. #include <tchar.h>
  10. #include <stdio.h>
  11. #include <d3d8.h>
  12. #include <d3dx8.h>
  13. #include <dxfile.h>
  14. #include <rmxfguid.h>
  15. #include <rmxftmpl.h>
  16. #include "D3DFile.h"
  17. #include "DXUtil.h"
  18.  
  19.  
  20.  
  21.  
  22. //-----------------------------------------------------------------------------
  23. // Name:
  24. // Desc:
  25. //-----------------------------------------------------------------------------
  26. CD3DMesh::CD3DMesh( TCHAR* strName )
  27. {
  28.     _tcscpy( m_strName, strName );
  29.     m_pSysMemMesh        = NULL;
  30.     m_pLocalMesh         = NULL;
  31.     m_dwNumMaterials     = 0L;
  32.     m_pMaterials         = NULL;
  33.     m_pTextures          = NULL;
  34.     m_bUseMaterials      = TRUE;
  35. }
  36.  
  37.  
  38.  
  39.  
  40. //-----------------------------------------------------------------------------
  41. // Name:
  42. // Desc:
  43. //-----------------------------------------------------------------------------
  44. CD3DMesh::~CD3DMesh()
  45. {
  46.     Destroy();
  47. }
  48.  
  49.  
  50.  
  51.  
  52. //-----------------------------------------------------------------------------
  53. // Name:
  54. // Desc:
  55. //-----------------------------------------------------------------------------
  56. HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
  57. {
  58.     TCHAR        strPath[MAX_PATH];
  59.     CHAR         strPathANSI[MAX_PATH];
  60.     LPD3DXBUFFER pAdjacencyBuffer = NULL;
  61.     LPD3DXBUFFER pMtrlBuffer = NULL;
  62.     HRESULT      hr;
  63.  
  64.     // Find the path for the file, and convert it to ANSI (for the D3DX API)
  65.     DXUtil_FindMediaFile( strPath, strFilename );
  66.     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
  67.  
  68.     // Load the mesh
  69.     if( FAILED( hr = D3DXLoadMeshFromX( strPathANSI, D3DXMESH_SYSTEMMEM, pd3dDevice, 
  70.                                         &pAdjacencyBuffer, &pMtrlBuffer, 
  71.                                         &m_dwNumMaterials, &m_pSysMemMesh ) ) )
  72.     {
  73.         return hr;
  74.     }
  75.  
  76.     // Optimize the mesh for performance
  77.     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
  78.                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
  79.                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
  80.     {
  81.         SAFE_RELEASE( pAdjacencyBuffer );
  82.         SAFE_RELEASE( pMtrlBuffer );
  83.         return hr;
  84.     }
  85.  
  86.     // Get material info for the mesh
  87.     // Get the array of materials out of the buffer
  88.     if( pMtrlBuffer && m_dwNumMaterials > 0 )
  89.     {
  90.         // Allocate memory for the materials and textures
  91.         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
  92.         m_pMaterials = new D3DMATERIAL8[m_dwNumMaterials];
  93.         m_pTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
  94.  
  95.         // Copy each material and create its texture
  96.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  97.         {
  98.             // Copy the material
  99.             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
  100.             m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;
  101.             m_pTextures[i]          = NULL;
  102.  
  103.             // Create a texture
  104.             if( d3dxMtrls[i].pTextureFilename )
  105.             {
  106.                 TCHAR strTexture[MAX_PATH];
  107.                 TCHAR strTextureTemp[MAX_PATH];
  108.                 DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename );
  109.                 DXUtil_FindMediaFile( strTexture, strTextureTemp );
  110.  
  111.                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
  112.                                                        &m_pTextures[i] ) ) )
  113.                     m_pTextures[i] = NULL;
  114.             }
  115.         }
  116.     }
  117.  
  118.     SAFE_RELEASE( pAdjacencyBuffer );
  119.     SAFE_RELEASE( pMtrlBuffer );
  120.  
  121.     return S_OK;
  122. }
  123.  
  124.  
  125.  
  126.  
  127. //-----------------------------------------------------------------------------
  128. // Name:
  129. // Desc:
  130. //-----------------------------------------------------------------------------
  131. HRESULT CD3DMesh::Create( LPDIRECT3DDEVICE8 pd3dDevice,
  132.                           LPDIRECTXFILEDATA pFileData )
  133. {
  134.     LPD3DXBUFFER pMtrlBuffer = NULL;
  135.     LPD3DXBUFFER pAdjacencyBuffer = NULL;
  136.     HRESULT      hr;
  137.  
  138.     // Load the mesh from the DXFILEDATA object
  139.     if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_SYSTEMMEM, pd3dDevice,
  140.                                           &pAdjacencyBuffer, &pMtrlBuffer, 
  141.                                           &m_dwNumMaterials, &m_pSysMemMesh ) ) )
  142.     {
  143.         return hr;
  144.     }
  145.  
  146.     // Optimize the mesh for performance
  147.     if( FAILED( hr = m_pSysMemMesh->OptimizeInplace(
  148.                         D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
  149.                         (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
  150.     {
  151.         SAFE_RELEASE( pAdjacencyBuffer );
  152.         SAFE_RELEASE( pMtrlBuffer );
  153.         return hr;
  154.     }
  155.  
  156.     // Get material info for the mesh
  157.     // Get the array of materials out of the buffer
  158.     if( pMtrlBuffer && m_dwNumMaterials > 0 )
  159.     {
  160.         // Allocate memory for the materials and textures
  161.         D3DXMATERIAL* d3dxMtrls = (D3DXMATERIAL*)pMtrlBuffer->GetBufferPointer();
  162.         m_pMaterials = new D3DMATERIAL8[m_dwNumMaterials];
  163.         m_pTextures  = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];
  164.  
  165.         // Copy each material and create its texture
  166.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  167.         {
  168.             // Copy the material
  169.             m_pMaterials[i]         = d3dxMtrls[i].MatD3D;
  170.             m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse;
  171.             m_pTextures[i]          = NULL;
  172.  
  173.             // Create a texture
  174.             if( d3dxMtrls[i].pTextureFilename )
  175.             {
  176.                 TCHAR strTexture[MAX_PATH];
  177.                 TCHAR strTextureTemp[MAX_PATH];
  178.                 DXUtil_ConvertAnsiStringToGeneric( strTextureTemp, d3dxMtrls[i].pTextureFilename );
  179.                 DXUtil_FindMediaFile( strTexture, strTextureTemp );
  180.  
  181.                 if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, 
  182.                                                        &m_pTextures[i] ) ) )
  183.                     m_pTextures[i] = NULL;
  184.             }
  185.         }
  186.     }
  187.  
  188.     SAFE_RELEASE( pAdjacencyBuffer );
  189.     SAFE_RELEASE( pMtrlBuffer );
  190.  
  191.     return S_OK;
  192. }
  193.  
  194.  
  195.  
  196.  
  197. //-----------------------------------------------------------------------------
  198. // Name:
  199. // Desc:
  200. //-----------------------------------------------------------------------------
  201. HRESULT CD3DMesh::SetFVF( LPDIRECT3DDEVICE8 pd3dDevice, DWORD dwFVF )
  202. {
  203.     LPD3DXMESH pTempSysMemMesh = NULL;
  204.     LPD3DXMESH pTempLocalMesh  = NULL;
  205.  
  206.     if( m_pSysMemMesh )
  207.     {
  208.         if( FAILED( m_pSysMemMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, dwFVF,
  209.                                                  pd3dDevice, &pTempSysMemMesh ) ) )
  210.             return E_FAIL;
  211.     }
  212.     if( m_pLocalMesh )
  213.     {
  214.         if( FAILED( m_pLocalMesh->CloneMeshFVF( 0L, dwFVF, pd3dDevice,
  215.                                                 &pTempLocalMesh ) ) )
  216.         {
  217.             SAFE_RELEASE( pTempSysMemMesh );
  218.             return E_FAIL;
  219.         }
  220.     }
  221.  
  222.     SAFE_RELEASE( m_pSysMemMesh );
  223.     SAFE_RELEASE( m_pLocalMesh );
  224.  
  225.     if( pTempSysMemMesh ) m_pSysMemMesh = pTempSysMemMesh;
  226.     if( pTempLocalMesh )  m_pLocalMesh  = pTempLocalMesh;
  227.  
  228.     // Compute normals in case the meshes have them
  229.     if( m_pSysMemMesh )
  230.         D3DXComputeNormals( m_pSysMemMesh, NULL );
  231.     if( m_pLocalMesh )
  232.         D3DXComputeNormals( m_pLocalMesh, NULL );
  233.  
  234.     return S_OK;
  235. }
  236.  
  237.  
  238.  
  239.  
  240. //-----------------------------------------------------------------------------
  241. // Name:
  242. // Desc:
  243. //-----------------------------------------------------------------------------
  244. HRESULT CD3DMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
  245. {
  246.     if( NULL == m_pSysMemMesh )
  247.         return E_FAIL;
  248.  
  249.     // Make a local memory version of the mesh. Note: because we are passing in
  250.     // no flags, the default behavior is to clone into local memory.
  251.     if( FAILED( m_pSysMemMesh->CloneMeshFVF( 0L, m_pSysMemMesh->GetFVF(),
  252.                                              pd3dDevice, &m_pLocalMesh ) ) )
  253.         return E_FAIL;
  254.  
  255.     return S_OK;
  256.  
  257. }
  258.  
  259.  
  260.  
  261.  
  262. //-----------------------------------------------------------------------------
  263. // Name:
  264. // Desc:
  265. //-----------------------------------------------------------------------------
  266. HRESULT CD3DMesh::InvalidateDeviceObjects()
  267. {
  268.     SAFE_RELEASE( m_pLocalMesh );
  269.  
  270.     return S_OK;
  271. }
  272.  
  273.  
  274.  
  275.  
  276. //-----------------------------------------------------------------------------
  277. // Name:
  278. // Desc:
  279. //-----------------------------------------------------------------------------
  280. HRESULT CD3DMesh::Destroy()
  281. {
  282.     InvalidateDeviceObjects();
  283.     for( UINT i=0; i<m_dwNumMaterials; i++ )
  284.         SAFE_RELEASE( m_pTextures[i] );
  285.     SAFE_DELETE_ARRAY( m_pTextures );
  286.     SAFE_DELETE_ARRAY( m_pMaterials );
  287.  
  288.     SAFE_RELEASE( m_pSysMemMesh );
  289.  
  290.     m_dwNumMaterials = 0L;
  291.  
  292.     return S_OK;
  293. }
  294.  
  295.  
  296.  
  297.  
  298. //-----------------------------------------------------------------------------
  299. // Name:
  300. // Desc:
  301. //-----------------------------------------------------------------------------
  302. HRESULT CD3DMesh::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
  303.                           BOOL bDrawAlphaSubsets )
  304. {
  305.     if( NULL == m_pLocalMesh )
  306.         return E_FAIL;
  307.  
  308.     // Frist, draw the subsets without alpha
  309.     if( bDrawOpaqueSubsets )
  310.     {
  311.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  312.         {
  313.             if( m_bUseMaterials )
  314.             {
  315.                 if( m_pMaterials[i].Diffuse.a < 1.0f )
  316.                     continue;
  317.                 pd3dDevice->SetMaterial( &m_pMaterials[i] );
  318.                 pd3dDevice->SetTexture( 0, m_pTextures[i] );
  319.             }
  320.             m_pLocalMesh->DrawSubset( i );
  321.         }
  322.     }
  323.  
  324.     // Then, draw the subsets with alpha
  325.     if( bDrawAlphaSubsets && m_bUseMaterials )
  326.     {
  327.         for( DWORD i=0; i<m_dwNumMaterials; i++ )
  328.         {
  329.             if( m_pMaterials[i].Diffuse.a == 1.0f )
  330.                 continue;
  331.  
  332.             // Set the material and texture
  333.             pd3dDevice->SetMaterial( &m_pMaterials[i] );
  334.             pd3dDevice->SetTexture( 0, m_pTextures[i] );
  335.             m_pLocalMesh->DrawSubset( i );
  336.         }
  337.     }
  338.  
  339.     return S_OK;
  340. }
  341.  
  342.  
  343.  
  344.  
  345. //-----------------------------------------------------------------------------
  346. // Name:
  347. // Desc:
  348. //-----------------------------------------------------------------------------
  349. CD3DFrame::CD3DFrame( TCHAR* strName )
  350. {
  351.     _tcscpy( m_strName, strName );
  352.     D3DXMatrixIdentity( &m_mat );
  353.     m_pMesh  = NULL;
  354.  
  355.     m_pChild = NULL;
  356.     m_pNext  = NULL;
  357. }
  358.  
  359.  
  360.  
  361.  
  362. //-----------------------------------------------------------------------------
  363. // Name:
  364. // Desc:
  365. //-----------------------------------------------------------------------------
  366. CD3DFrame::~CD3DFrame()
  367. {
  368.     SAFE_DELETE( m_pChild );
  369.     SAFE_DELETE( m_pNext );
  370. }
  371.  
  372.  
  373.  
  374.  
  375. //-----------------------------------------------------------------------------
  376. // Name:
  377. // Desc:
  378. //-----------------------------------------------------------------------------
  379. BOOL CD3DFrame::EnumMeshes( BOOL (*EnumMeshCB)(CD3DMesh*,VOID*),
  380.                             VOID* pContext )
  381. {
  382.     if( m_pMesh )
  383.         EnumMeshCB( m_pMesh, pContext );
  384.     if( m_pChild )
  385.         m_pChild->EnumMeshes( EnumMeshCB, pContext );
  386.     if( m_pNext )
  387.         m_pNext->EnumMeshes( EnumMeshCB, pContext );
  388.  
  389.     return TRUE;
  390. }
  391.  
  392.  
  393.  
  394.  
  395. //-----------------------------------------------------------------------------
  396. // Name:
  397. // Desc:
  398. //-----------------------------------------------------------------------------
  399. CD3DMesh* CD3DFrame::FindMesh( TCHAR* strMeshName )
  400. {
  401.     CD3DMesh* pMesh;
  402.  
  403.     if( m_pMesh )
  404.         if( !lstrcmpi( m_pMesh->m_strName, strMeshName ) )
  405.             return m_pMesh;
  406.  
  407.     if( m_pChild )
  408.         if( NULL != ( pMesh = m_pChild->FindMesh( strMeshName ) ) )
  409.             return pMesh;
  410.  
  411.     if( m_pNext )
  412.         if( NULL != ( pMesh = m_pNext->FindMesh( strMeshName ) ) )
  413.             return pMesh;
  414.  
  415.     return NULL;
  416. }
  417.  
  418.  
  419.  
  420.  
  421. //-----------------------------------------------------------------------------
  422. // Name:
  423. // Desc:
  424. //-----------------------------------------------------------------------------
  425. CD3DFrame* CD3DFrame::FindFrame( TCHAR* strFrameName )
  426. {
  427.     CD3DFrame* pFrame;
  428.  
  429.     if( !lstrcmpi( m_strName, strFrameName ) )
  430.         return this;
  431.  
  432.     if( m_pChild )
  433.         if( NULL != ( pFrame = m_pChild->FindFrame( strFrameName ) ) )
  434.             return pFrame;
  435.  
  436.     if( m_pNext )
  437.         if( NULL != ( pFrame = m_pNext->FindFrame( strFrameName ) ) )
  438.             return pFrame;
  439.  
  440.     return NULL;
  441. }
  442.  
  443.  
  444.  
  445.  
  446. //-----------------------------------------------------------------------------
  447. // Name:
  448. // Desc:
  449. //-----------------------------------------------------------------------------
  450. HRESULT CD3DFrame::Destroy()
  451. {
  452.     if( m_pMesh )  m_pMesh->Destroy();
  453.     if( m_pChild ) m_pChild->Destroy();
  454.     if( m_pNext )  m_pNext->Destroy();
  455.  
  456.     SAFE_DELETE( m_pMesh );
  457.     SAFE_DELETE( m_pNext );
  458.     SAFE_DELETE( m_pChild );
  459.  
  460.     return S_OK;
  461. }
  462.  
  463.  
  464.  
  465.  
  466. //-----------------------------------------------------------------------------
  467. // Name:
  468. // Desc:
  469. //-----------------------------------------------------------------------------
  470. HRESULT CD3DFrame::RestoreDeviceObjects( LPDIRECT3DDEVICE8 pd3dDevice )
  471. {
  472.     if( m_pMesh )  m_pMesh->RestoreDeviceObjects( pd3dDevice );
  473.     if( m_pChild ) m_pChild->RestoreDeviceObjects( pd3dDevice );
  474.     if( m_pNext )  m_pNext->RestoreDeviceObjects( pd3dDevice );
  475.     return S_OK;
  476. }
  477.  
  478.  
  479.  
  480.  
  481. //-----------------------------------------------------------------------------
  482. // Name:
  483. // Desc:
  484. //-----------------------------------------------------------------------------
  485. HRESULT CD3DFrame::InvalidateDeviceObjects()
  486. {
  487.     if( m_pMesh )  m_pMesh->InvalidateDeviceObjects();
  488.     if( m_pChild ) m_pChild->InvalidateDeviceObjects();
  489.     if( m_pNext )  m_pNext->InvalidateDeviceObjects();
  490.     return S_OK;
  491. }
  492.  
  493.  
  494.  
  495.  
  496. //-----------------------------------------------------------------------------
  497. // Name:
  498. // Desc:
  499. //-----------------------------------------------------------------------------
  500. HRESULT CD3DFrame::Render( LPDIRECT3DDEVICE8 pd3dDevice, BOOL bDrawOpaqueSubsets,
  501.                            BOOL bDrawAlphaSubsets, D3DXMATRIX* pmatWorldMatrix )
  502. {
  503.     // For pure devices, specify the world transform. If the world transform is not
  504.     // specified on pure devices, this function will fail.
  505.  
  506.     D3DXMATRIX matSavedWorld, matWorld;
  507.  
  508.     if ( NULL == pmatWorldMatrix )
  509.         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  510.     else
  511.         matSavedWorld = *pmatWorldMatrix;
  512.  
  513.     D3DXMatrixMultiply( &matWorld, &m_mat, &matSavedWorld );
  514.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  515.  
  516.     if( m_pMesh )
  517.         m_pMesh->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets );
  518.  
  519.     if( m_pChild )
  520.         m_pChild->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matWorld );
  521.  
  522.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  523.  
  524.     if( m_pNext )
  525.         m_pNext->Render( pd3dDevice, bDrawOpaqueSubsets, bDrawAlphaSubsets, &matSavedWorld );
  526.  
  527.     return S_OK;
  528. }
  529.  
  530.  
  531.  
  532.  
  533. //-----------------------------------------------------------------------------
  534. // Name:
  535. // Desc:
  536. //-----------------------------------------------------------------------------
  537. HRESULT CD3DFile::LoadFrame( LPDIRECT3DDEVICE8 pd3dDevice,
  538.                              LPDIRECTXFILEDATA pFileData,
  539.                              CD3DFrame* pParentFrame )
  540. {
  541.     LPDIRECTXFILEDATA   pChildData = NULL;
  542.     LPDIRECTXFILEOBJECT pChildObj = NULL;
  543.     const GUID* pGUID;
  544.     DWORD       cbSize;
  545.     CD3DFrame*  pCurrentFrame;
  546.     HRESULT     hr;
  547.  
  548.     // Get the type of the object
  549.     if( FAILED( hr = pFileData->GetType( &pGUID ) ) )
  550.         return hr;
  551.  
  552.     if( *pGUID == TID_D3DRMMesh )
  553.     {
  554.         hr = LoadMesh( pd3dDevice, pFileData, pParentFrame );
  555.         if( FAILED(hr) )
  556.             return hr;
  557.     }
  558.     if( *pGUID == TID_D3DRMFrameTransformMatrix )
  559.     {
  560.         D3DXMATRIX* pmatMatrix;
  561.         hr = pFileData->GetData( NULL, &cbSize, (VOID**)&pmatMatrix );
  562.         if( FAILED(hr) )
  563.             return hr;
  564.  
  565.         // Update the parent's matrix with the new one
  566.         pParentFrame->SetMatrix( pmatMatrix );
  567.     }
  568.     if( *pGUID == TID_D3DRMFrame )
  569.     {
  570.         // Get the frame name
  571.         CHAR  strAnsiName[512] = "";
  572.         TCHAR strName[MAX_PATH];
  573.         DWORD dwNameLength;
  574.         pFileData->GetName( NULL, &dwNameLength );
  575.         if( dwNameLength > 0 )
  576.             pFileData->GetName( strAnsiName, &dwNameLength );
  577.         DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
  578.  
  579.         // Create the frame
  580.         pCurrentFrame = new CD3DFrame( strName );
  581.  
  582.         pCurrentFrame->m_pNext = pParentFrame->m_pChild;
  583.         pParentFrame->m_pChild = pCurrentFrame;
  584.  
  585.         // Enumerate child objects
  586.         while( SUCCEEDED( pFileData->GetNextObject( &pChildObj ) ) )
  587.         {
  588.             // Query the child for its FileData
  589.             hr = pChildObj->QueryInterface( IID_IDirectXFileData,
  590.                                             (VOID**)&pChildData );
  591.             if( SUCCEEDED(hr) )
  592.             {
  593.                 hr = LoadFrame( pd3dDevice, pChildData, pCurrentFrame );
  594.                 pChildData->Release();
  595.             }
  596.  
  597.             pChildObj->Release();
  598.  
  599.             if( FAILED(hr) )
  600.                 return hr;
  601.         }
  602.     }
  603.  
  604.     return S_OK;
  605. }
  606.  
  607.  
  608.  
  609.  
  610. //-----------------------------------------------------------------------------
  611. // Name:
  612. // Desc:
  613. //-----------------------------------------------------------------------------
  614. HRESULT CD3DFile::LoadMesh( LPDIRECT3DDEVICE8 pd3dDevice,
  615.                             LPDIRECTXFILEDATA pFileData,
  616.                             CD3DFrame* pParentFrame )
  617. {
  618.     // Currently only allowing one mesh per frame
  619.     if( pParentFrame->m_pMesh )
  620.         return E_FAIL;
  621.  
  622.     // Get the mesh name
  623.     CHAR  strAnsiName[512] = {0};
  624.     TCHAR strName[MAX_PATH];
  625.     DWORD dwNameLength;
  626.     pFileData->GetName( NULL, &dwNameLength );
  627.     if( dwNameLength > 0 )
  628.         pFileData->GetName( strAnsiName, &dwNameLength );
  629.     DXUtil_ConvertAnsiStringToGeneric( strName, strAnsiName );
  630.  
  631.     // Create the mesh
  632.     pParentFrame->m_pMesh = new CD3DMesh( strName );
  633.     pParentFrame->m_pMesh->Create( pd3dDevice, pFileData );
  634.  
  635.     return S_OK;
  636. }
  637.  
  638.  
  639.  
  640.  
  641. //-----------------------------------------------------------------------------
  642. // Name:
  643. // Desc:
  644. //-----------------------------------------------------------------------------
  645. HRESULT CD3DFile::CreateFromResource( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strResource, TCHAR* strType )
  646. {
  647.     LPDIRECTXFILE           pDXFile   = NULL;
  648.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  649.     LPDIRECTXFILEDATA       pFileData = NULL;
  650.     HRESULT hr;
  651.  
  652.     // Create a x file object
  653.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  654.         return E_FAIL;
  655.  
  656.     // Register templates for d3drm and patch extensions.
  657.     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
  658.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  659.     {
  660.         pDXFile->Release();
  661.         return E_FAIL;
  662.     }
  663.     
  664.     CHAR strTypeAnsi[MAX_PATH];
  665.     DXUtil_ConvertGenericStringToAnsi( strTypeAnsi, strType );
  666.  
  667.     DXFILELOADRESOURCE dxlr;
  668.     dxlr.hModule = NULL;
  669.     dxlr.lpName = strResource;
  670.     dxlr.lpType = (TCHAR*) strTypeAnsi;
  671.  
  672.     // Create enum object
  673.     hr = pDXFile->CreateEnumObject( (VOID*)&dxlr, DXFILELOAD_FROMRESOURCE, 
  674.                                     &pEnumObj );
  675.     if( FAILED(hr) )
  676.     {
  677.         pDXFile->Release();
  678.         return hr;
  679.     }
  680.  
  681.     // Enumerate top level objects (which are always frames)
  682.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  683.     {
  684.         hr = LoadFrame( pd3dDevice, pFileData, this );
  685.         pFileData->Release();
  686.         if( FAILED(hr) )
  687.         {
  688.             pEnumObj->Release();
  689.             pDXFile->Release();
  690.             return E_FAIL;
  691.         }
  692.     }
  693.  
  694.     SAFE_RELEASE( pFileData );
  695.     SAFE_RELEASE( pEnumObj );
  696.     SAFE_RELEASE( pDXFile );
  697.  
  698.     return S_OK;
  699. }
  700.  
  701.  
  702.  
  703.  
  704. //-----------------------------------------------------------------------------
  705. // Name:
  706. // Desc:
  707. //-----------------------------------------------------------------------------
  708. HRESULT CD3DFile::Create( LPDIRECT3DDEVICE8 pd3dDevice, TCHAR* strFilename )
  709. {
  710.     LPDIRECTXFILE           pDXFile   = NULL;
  711.     LPDIRECTXFILEENUMOBJECT pEnumObj  = NULL;
  712.     LPDIRECTXFILEDATA       pFileData = NULL;
  713.     HRESULT hr;
  714.  
  715.     // Create a x file object
  716.     if( FAILED( hr = DirectXFileCreate( &pDXFile ) ) )
  717.         return E_FAIL;
  718.  
  719.     // Register templates for d3drm and patch extensions.
  720.     if( FAILED( hr = pDXFile->RegisterTemplates( (VOID*)D3DRM_XTEMPLATES,
  721.                                                  D3DRM_XTEMPLATE_BYTES ) ) )
  722.     {
  723.         pDXFile->Release();
  724.         return E_FAIL;
  725.     }
  726.  
  727.     // Find the path to the file, and convert it to ANSI (for the D3DXOF API)
  728.     TCHAR strPath[MAX_PATH];
  729.     CHAR  strPathANSI[MAX_PATH];
  730.     DXUtil_FindMediaFile( strPath, strFilename );
  731.     DXUtil_ConvertGenericStringToAnsi( strPathANSI, strPath );
  732.     
  733.     // Create enum object
  734.     hr = pDXFile->CreateEnumObject( (VOID*)strPathANSI, DXFILELOAD_FROMFILE, 
  735.                                     &pEnumObj );
  736.     if( FAILED(hr) )
  737.     {
  738.         pDXFile->Release();
  739.         return hr;
  740.     }
  741.  
  742.     // Enumerate top level objects (which are always frames)
  743.     while( SUCCEEDED( pEnumObj->GetNextDataObject( &pFileData ) ) )
  744.     {
  745.         hr = LoadFrame( pd3dDevice, pFileData, this );
  746.         pFileData->Release();
  747.         if( FAILED(hr) )
  748.         {
  749.             pEnumObj->Release();
  750.             pDXFile->Release();
  751.             return E_FAIL;
  752.         }
  753.     }
  754.  
  755.     SAFE_RELEASE( pFileData );
  756.     SAFE_RELEASE( pEnumObj );
  757.     SAFE_RELEASE( pDXFile );
  758.  
  759.     return S_OK;
  760. }
  761.  
  762.  
  763.  
  764.  
  765. //-----------------------------------------------------------------------------
  766. // Name:
  767. // Desc:
  768. //-----------------------------------------------------------------------------
  769. HRESULT CD3DFile::Render( LPDIRECT3DDEVICE8 pd3dDevice, D3DXMATRIX* pmatWorldMatrix )
  770. {
  771.  
  772.     // For pure devices, specify the world transform. If the world transform is not
  773.     // specified on pure devices, this function will fail.
  774.  
  775.     // Set up the world transformation
  776.     D3DXMATRIX matSavedWorld, matWorld;
  777.  
  778.     if ( NULL == pmatWorldMatrix )
  779.         pd3dDevice->GetTransform( D3DTS_WORLD, &matSavedWorld );
  780.     else
  781.         matSavedWorld = *pmatWorldMatrix;
  782.  
  783.     D3DXMatrixMultiply( &matWorld, &matSavedWorld, &m_mat );
  784.     pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
  785.  
  786.     // Render opaque subsets in the meshes
  787.     if( m_pChild )
  788.         m_pChild->Render( pd3dDevice, TRUE, FALSE, &matWorld );
  789.  
  790.     // Enable alpha blending
  791.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  792.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
  793.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  794.  
  795.     // Render alpha subsets in the meshes
  796.     if( m_pChild )
  797.         m_pChild->Render( pd3dDevice, FALSE, TRUE, &matWorld );
  798.  
  799.     // Restore state
  800.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
  801.     pd3dDevice->SetTransform( D3DTS_WORLD, &matSavedWorld );
  802.  
  803.     return S_OK;
  804. }
  805.  
  806.  
  807.  
  808.  
  809.